// =======================================================================
// 
//       Filename:  parser.hpp
// 
//    Description:  
// 
//        Version:  1.0
//        Created:  25.03.2010 21:18:50
//       Revision:  none
//       Compiler:  g++
// 
//         Author:  Dominik 'domachine' Burgdörfer (-), dominik.burgdoerfer@googlemail.com
//        Company:  -
// 
// =======================================================================


#ifndef  PARSER_INC
#define  PARSER_INC
#include "types/string.hpp"
#include "utils/citerator.hpp"
#include "elementstack.hpp"
#include <stdexcept>
#include <map>
#include <list>
#include <boost/shared_ptr.hpp>
#include <boost/filesystem.hpp>

namespace webplodder {
    // Forward declaration
    namespace types {
        class Object;
    }

    namespace elements {
        class Script;
        class Variable;
        class Element;
    }

    /**
     * This class parses a template file
     * and interprets commands and scripts on the fly.
     * @brief This class parses a template file.
     */
    class Parser {
        public:
            /**
             * @brief Constructs default Parser.
             */
            Parser();

            /**
             * @brief Launches the parsing process.
             * @throw std::logic_error Thrown if a script is detected
             *                         and no rule defined
             * @throw SyntaxError Thrown if an syntax error is detected.
             */
            void parse(ElementStack& stack, std::istream* in = 0);

            int line() const;

        private:
            void safelyIncr();
            void skipWhiteSpace();
            boost::shared_ptr<elements::Script> parseScript(
                    ElementStack& elementStack);
            boost::shared_ptr<elements::Variable> parseVar(
                    ElementStack& elementStack);
            boost::shared_ptr<elements::Element> 
                parseCmd(ElementStack& elementStack);
            boost::shared_ptr<types::String>
                parseString();
            boost::shared_ptr<types::Object>
                parseNumber();

            utils::CIterator mIterator;
            int m_line;
            int m_lineOffset;
            boost::filesystem::path m_filePath;
    };
}
#endif   // ----- #ifndef PARSER_INC  -----
